if not spy then

dofile (getScriptPath() .. "\\..\\processor\\processor.lua")
dofile (getScriptPath() .. "\\..\\processor\\watchdog.lua")
dofile (getScriptPath() .. "\\..\\processor\\log.lua")
dofile (getScriptPath() .. "\\..\\processor\\notify.lua")
dofile (getScriptPath() .. "\\..\\processor\\DataSource.lua")

dofile (getScriptPath() .. "\\..\\lib\\lib.lua")

spy = {handlers = {},
	callbacks = {},
	quotes = "quotes.txt",
	start_delay = 10000,
	log = "spy"
}

function spy.callback(v)
	if spy.do_callback then
		--message(lib:toline(v))
		local cb = spy.callbacks[v.interval]
		if cb then
			for k, f in pairs(cb) do
				f(v)
			end
		end
	end
end

processor:AddHandler("OnRun", function(t)
	--processor:stop(0)
end)

processor:AddHandler("DataSource", function(data)
	if spy.handlers_period then
		local t = processor:IsDelay(spy.handlers_time, spy.handlers_period)
		if t then
			spy.handlers_time = t
		else
			return
		end
	end
	
	local price, datetime
	
	for k, v in pairs(spy.handlers[data.interval]) do
		price, datetime = v(data.ds)
		if price and datetime then
			if datetime.hint__ then
				message(data.ds.instrument.code .. " " .. datetime.hint__)
				spy:SaveLabels(datetime.sec_code__, datetime.labels__)
				if data.interval == INTERVAL_TICK and pattern.ticks and pattern.ticks.SaveLabel then
					pattern.ticks:SaveLabel(datetime, price)
				end
			end
			
			if datetime.notify__ and not spy.no_notify then
				if spy.notify_prefix then
					processor:notify(spy.notify_prefix .. " " .. datetime.notify__)
				else
					processor:notify(datetime.notify__)
				end
			end
		end
	end
end)

processor:AddTimer(function(t)
	if spy.isStarted then return end
	if not lib:isConnected() then return end
	if not lib:isTradeTime() then return end
	
	client_code = lib:GetUser()
	if not client_code then return end
	
	script_id = client_code .. "#" .. script_name
	log_file = lib.path.log .. spy.log .. ".log"

	spy.semafore_ds = lib.path.semafores .. "ds" -- .. client_code
	
	spy.isStarted = 1
	spy.start_timer = processor:GetTime()
	
	processor:InitLog(log_file)
	--message("Log " .. log_file)
end)

processor:AddTimer(function(t)
	if spy.isStarted ~= 1 then return end
	if not processor:IsDelay(spy.start_timer, spy.start_delay) then return end
	
	lib:remove(spy.semafore_ds)
	if lib:exists(spy.semafore_ds) then return end
	
	spy.h_semafore_ds = io.open(spy.semafore_ds, "w")
	if spy.h_semafore_ds then
		spy.h_semafore_ds:write(script_id .. "\n")
		spy.h_semafore_ds:flush()
		spy.isStarted = 2
		spy.start_timer = processor:GetTime()
	end
end)

processor:AddTimer(function(t)
	if spy.isStarted ~= 2 then return end
	
	spy.isStarted = 3
	spy.start_timer = processor:GetTime()
	
	processor:log(script_id .. " loading")
	
	spy:LoadSecurities()
end)

processor:AddTimer(function()
	if spy.isStarted ~= 4 then return end
	if ticks and ticks.clean then
		ticks:clean()
	end
end)

processor:AddTimer(function()
	if spy.isStarted == 3 and processor.ds.started then
		spy.isStarted = 4
		spy.start_timer = processor:GetTime()
		processor:SetTimer(2000)
		processor:InitWatchdog(script_id)
		spy.h_semafore_ds:close()
		spy.h_semafore_ds = nil
		lib:remove(spy.semafore_ds)
	
		processor:log(script_id .. " started " .. processor.ds.started)
	end
end)

processor:AddTimer(function()
	if spy.isStarted ~= 4 then return end
	local end_time = os.sysdate()
	local now = lib:tickseconds(end_time)
	end_time.hour = 9
	end_time.min = 55
	end_time.sec = 0
	end_time.ms = 0
	end_time.mcs = 0
	local start_time = lib:tickseconds(end_time)
	end_time.hour = 18
	end_time.min = 39
	local end_time = lib:tickseconds(end_time)

	spy.do_callback = now >= start_time and now < end_time
	--spy.do_callback = true
end)

processor:AddStop(function()
	if spy.h_semafore_ds then
		spy.h_semafore_ds:close()
		spy.h_semafore_ds = nil
	end
end)

function spy:LoadSecurities()
	local list, callback
	local n = 0
	
	local thread = string.match(script_name, "[%.%-](%d+)$")
	if thread then
		thread = int(thread)
	else
		thread = nil
	end
	
	if pattern and pattern.ticks then
		for k, v in pairs(pattern.ticks) do
			if type(v) == "table" and v.Init then
				v.Init()
			end
		end
	end
	
	for k in pairs(self.handlers) do
		if self.callbacks[k] then
			callback = self.callback
		else
			callback = nil
		end
		processor.ds:Init(lib.path.init .. self.quotes, k, callback, thread)
		
		list = processor.ds:GetSecuritiesList(k)
		if list and #list > 0 then
			if ticks and ticks.load then
				for i, v in ipairs(list) do
					hf = ticks:load(v.code, lib:ticktime())
				end
			end
			n = n + #list
		end
	end
	
	collectgarbage("collect")
	
	if n == 0 then
		processor:SetTimer(5000)
		--processor:stop(3)
	end
	
	return n
end

function spy:SaveLabels(sec_code, labels)
	if self.no_label then return end
	lib:SaveLabels(sec_code, labels)
end

end	-- of file
